package com.example.easyexcel.service.impl;

import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.example.easyexcel.dao.AssetTargetInfoMapper;
import com.example.easyexcel.listener.HutoolSheetProcessor;
import com.example.easyexcel.service.HutoolAssetTargetInfoService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;

@Service
@RequiredArgsConstructor
@Slf4j
public class HutoolAssetTargetInfoServiceImpl implements HutoolAssetTargetInfoService {

    private final AssetTargetInfoMapper assetTargetInfoMapper;
    private static final int BATCH_SIZE = 2000;

    @Override
    public void importTargetExcel(MultipartFile file) {
        long totalStartTime = System.currentTimeMillis();
        Path tempFile = null;

        try {
            log.info("开始使用Hutool导入Excel文件: {}", file.getOriginalFilename());

            // 创建临时文件
            tempFile = Files.createTempFile("hutool-excel-import-", ".xlsx");
            file.transferTo(tempFile);
            log.info("临时文件创建成功: {}", tempFile.toString());

            // 获取sheet数量
            int sheetCount = getSheetCount(tempFile.toString());
            log.info("检测到Excel共有 {} 个sheet", sheetCount);

            // 处理所有sheet
            processAllSheets(tempFile.toString(), sheetCount);

            long totalElapsedTime = System.currentTimeMillis() - totalStartTime;
            log.info("Hutool Excel导入完成! 总耗时: {} 毫秒", totalElapsedTime);

        } catch (Exception e) {
            long totalElapsedTime = System.currentTimeMillis() - totalStartTime;
            log.error("Hutool Excel导入失败，已耗时: {} 毫秒", totalElapsedTime, e);
            throw new RuntimeException("Hutool Excel导入失败: " + e.getMessage(), e);
        } finally {
            // 清理临时文件
            if (tempFile != null) {
                try {
                    Files.deleteIfExists(tempFile);
                    log.debug("临时文件已清理");
                } catch (Exception e) {
                    log.warn("删除临时文件失败: {}", e.getMessage());
                }
            }
        }
    }

    /**
     * 获取Excel中的sheet数量
     */
    private int getSheetCount(String filePath) {
        try (ExcelReader excelReader = ExcelUtil.getReader(filePath)) {
            return excelReader.getSheetCount();
        } catch (Exception e) {
            log.warn("获取sheet数量失败，默认使用1个sheet: {}", e.getMessage());
            return 1;
        }
    }

    /**
     * 处理所有sheet
     */
    private void processAllSheets(String filePath, int sheetCount) {
        long processStartTime = System.currentTimeMillis();
        int totalProcessed = 0;
        int totalFailed = 0;

        for (int sheetIndex = 0; sheetIndex < sheetCount; sheetIndex++) {
            long sheetStartTime = System.currentTimeMillis();

            try {
                log.info("开始处理第 {} 个sheet", sheetIndex + 1);

                // 为每个sheet创建处理实例
                HutoolSheetProcessor processor = new HutoolSheetProcessor(assetTargetInfoMapper, BATCH_SIZE);

                // 读取指定sheet
                try (ExcelReader reader = ExcelUtil.getReader(filePath, sheetIndex)) {
                    List<List<Object>> sheetData = reader.read();
                    processor.processSheet(sheetData, sheetIndex);
                }

                totalProcessed += processor.getProcessedCount();
                totalFailed += processor.getFailedCount();

                long sheetTime = System.currentTimeMillis() - sheetStartTime;
                log.info("第 {} 个sheet处理完成, 成功: {} 条, 失败: {} 条, 耗时: {} 毫秒",
                        sheetIndex + 1, processor.getProcessedCount(), processor.getFailedCount(), sheetTime);

            } catch (Exception e) {
                long sheetTime = System.currentTimeMillis() - sheetStartTime;
                log.error("第 {} 个sheet处理失败, 已耗时: {} 毫秒", sheetIndex + 1, sheetTime, e);
                totalFailed++;
            }
        }

        long totalTime = System.currentTimeMillis() - processStartTime;
        log.info("所有sheet处理完毕! 总计成功: {} 条, 失败: {} 条, 总耗时: {} 毫秒",
                totalProcessed, totalFailed, totalTime);
    }
}